package com.fingard.dsp.bank.directbank.hbc01;

import java.io.File;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.directbank.hsbc01.EnumDirType;
import com.fingard.dsp.bank.directbank.hsbc01.HSBC01Base;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpReceiver;

/**
 * @author XueJy on 2018/9/19.
 * @version 1.0
 */
public class HBC01Transaction extends HBC01Base implements ITransaction {
    DecimalFormat  df = new DecimalFormat("0.00");

    static Pattern pattern = Pattern.compile("[a-zA-Z]");

    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            //账号地区区域码
            //查询起止时间
            Calendar calendarFrom = Calendar.getInstance();
            calendarFrom.setTime(p_req7516.getDateFrom());
            Calendar calendarTo = Calendar.getInstance();
            calendarTo.setTime(p_req7516.getDateTo());
            //超出当前时间则使用当前 时间
            if (calendarTo.getTime().getTime() > System.currentTimeMillis()) {
                calendarTo.setTime(new Date());
            }
            //List<String[]> prebalances = new ArrayList<>();
            //存放历时余额详情Map Key为日期yyyy-MM-dd ,Value为当日余额
            int numOfDate = calendarTo.get(Calendar.DAY_OF_YEAR) - calendarFrom.get(Calendar.DAY_OF_YEAR) + 1;
            List<String> list = new ArrayList<String>();
            for (int x = 0; x < numOfDate; x++) {
                //key :yyyyMMdd  value String[]
                list.add(Format.Date8Format.format(calendarFrom.getTime()));
                calendarFrom.add(Calendar.DAY_OF_MONTH, 1);
            }
            //保存的时候日期要减一天
            HSBC01Base hsbc01Base = new HSBC01Base();
            hsbc01Base.bankFront = this.bankFront;
            hsbc01Base.reqHeader = this.reqHeader;
            hsbc01Base.sbLog = this.sbLog;
            FtpReceiver ftpReceiver = hsbc01Base.downloadFile();
            if (ftpReceiver != null) {
                if (ConnState.FAIL.equals(ftpReceiver.connState) || (!ftpReceiver.isCompleted && !"file not exists".equals(ftpReceiver.connState))) {
                    retAts.writeRespInfo(ftpReceiver.connState + "+" + ftpReceiver.connMsg);
                    retAts.writeRespCode("-1");
                    return retAts;
                }
            }

            boolean isToday = false;
            if (list.size() == 1 && list.get(0).equals(Format.Date8Format.format(new Date()))) {
                isToday = true;
            }


            parseMT(list, retAts, p_req7516, isToday);
        } catch (Exception ex) {
            WriteBankLogLn(ex);
            if (!retAts.hasWrittenRespCode) {
                retAts.writeRespCode("-1");
            }
            if (!retAts.hasWrittenRespInfo) {
                retAts.writeRespInfo("历史明细查询异常。");
            }
            retAts.writeEnd();
            return retAts;
        }
        if (!retAts.hasWrittenRespCode) {
            retAts.writeRespCode("0");
        }
        if (!retAts.hasWrittenRespInfo) {
            retAts.writeRespInfo("查询成功。");
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.reqHeader);
        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;
        String tmpStrToday = Format.Date8Format.format(new Date());
        //设置开始时间和结束时间都为当天
        tmpReq7516.dateFrom = tmpStrToday;
        tmpReq7516.dateTo = tmpStrToday;
        return d_7516_HisTrans(tmpReq7516);
    }

    void parseMT(List<String> dateList, RetAtsTrans retAts, Req7516HisTrans txnRequest, boolean isToday) throws Exception {
        HSBC01Base hsbc01Base = new HSBC01Base();
        hsbc01Base.bankFront = this.bankFront;
        hsbc01Base.reqHeader = this.reqHeader;
        hsbc01Base.sbLog = this.sbLog;

        String actNum = txnRequest.actNum;
        String actArea = txnRequest.actArea;
        //region 读取交易明细信息

        String actmap = getBankConfig().getMapValueByKey("ReportActMapping", actNum);
        if (actmap== null || "".equals(actmap)) {
            actmap = actNum;
        }

        for (String history : dateList) {
            //指定日期路径
            String fileDatePath = hsbc01Base.getReceivePath(EnumDirType.MT940.getValue(), Format.Date8Format.parse(history.substring(0, 6) + history.substring(6, 8)));
            if (isToday) {
                fileDatePath = hsbc01Base.getReceivePath(EnumDirType.MT942.getValue(), Format.Date8Format.parse(history.substring(0, 6) + history.substring(6, 8)));
            }
            List<String> fileNames = getDirectoryAllFileName(fileDatePath);
            List<String> fileList = new ArrayList<String>();
            //STMTCN.EJ321.091904534678.088251418012.TXT
            for (String filename : fileNames) {
                String[] filesplit = filename.split("\\.");
                if (filesplit.length > 3) {
                    if (filesplit[3].equals(actNum)) {
                        fileList.add(filename);
                    }
                }
            }

            for (String fileName : fileList) {
                try {
                    String alltext = "";
                    synchronized (this) {
                        //读取文件内容
                        alltext = FileHelper.readFileText(fileDatePath + File.separator + fileName, getCharset());
                    }
                    //对单个文件进行解析查找对应的账号明细信息 //:25: 跟账号
                    String spliter = "\n";
                    if (alltext.contains("\r\n")) {
                        spliter = "\r\n";
                    }
                    //恒生发送的文件 账号 带-     :25:511-055915-020 ALLIANZ CN LIFE INS
                    String actNumTmp = alltext.split(":25:")[1].split(spliter)[0];
                    if (actNumTmp.startsWith(actmap)) {
                        String[] openingBal1 = null;
                        String startBalance = "";
                        String cur = "CNY";
                        if (!isToday) {
                            //获取openingBalance
                            if (alltext.contains(":60F:")) {
                                openingBal1 = alltext.split(":60F:");//:60M:
                            } else {
                                openingBal1 = alltext.split(":60M:");//:60M:
                            }
                            //明细查询余额
                            String openingBal2 = (openingBal1[1].split(spliter))[0];
                            //金额
                            startBalance = openingBal2.substring(10);
                            cur = openingBal2.substring(7, 10);
                            startBalance = convertCommaToPoint(startBalance);
                            //若为D前面增加－
                            if ("D".equals(openingBal2.substring(0, 1))) {
                                startBalance = "-" + startBalance;
                            }
                        }
                        String[] txns = alltext.split(":61:");
                        if (txns.length > 1) {
                            for (int i = 1; i < txns.length; i++) {
                                RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                String valueDateStr = txns[i].substring(0, 6);
                                Date valueDate = Format.Date6Format.parse(valueDateStr);
                                String transDateStr = txns[i].substring(6, 10);
                                tmpRetDetail.cur = convertCurToATS(cur);
                                tmpRetDetail.actArea = actArea;
                                tmpRetDetail.actNum = actNum;
                                tmpRetDetail.valueDate = Format.Date10Format.format(valueDate);
                                valueDate.setMonth(Integer.parseInt(transDateStr.substring(0, 2)) - 1);
                                valueDate.setDate(Integer.parseInt(transDateStr.substring(2, 4)));
                                tmpRetDetail.tranDate = Format.Date10Format.format(valueDate);
                                tmpRetDetail.tranTime = Format.DateTimeFormat.format(valueDate);
                                //region 确定借贷标志 Debit / Credit Flag （1:支出、2:收入）
                                String cdFlag = "";
                                String cdflag = txns[i].substring(10, 11);
                                int amtStart = 12;
                                if ("D".equals(cdflag)) {
                                    cdFlag = "1";
                                } else if ("C".equals(cdflag)) {
                                    cdFlag = "2";
                                } else {
                                    cdflag = txns[i].substring(10, 12);
                                    if ("RD".equals(cdflag)) {
                                        cdFlag = "2";
                                    } else {
                                        cdFlag = "1";
                                    }
                                    amtStart++;
                                }
                                tmpRetDetail.cdFlag = cdFlag;
                                //计算当前余额
                                //获取金额
                                String trAmount = txns[i].substring(amtStart, txns[i].indexOf(",") + 3);
                                Matcher m = pattern.matcher(trAmount);
                                if (m.find()) {
                                    trAmount= trAmount.substring(0, trAmount.indexOf(m.group(0)));
                                }
                                trAmount = convertCommaToPoint(trAmount);
                                BigDecimal amount = new BigDecimal(trAmount);
                                //交易金额
                                tmpRetDetail.tranAmt = df.format(amount);
                                if (!isToday) {
                                    BigDecimal openingbalance = new BigDecimal(startBalance);
                                    //openingbalance已经包含正负.
                                    if ("1".equals(cdFlag)) {
                                        //保留两位小数位
                                        startBalance = df.format(openingbalance.subtract(amount));
                                        //保留两位小数位
                                    } else {
                                        startBalance = df.format(openingbalance.add(amount));
                                    }
                                    //交易金额
                                    //账户余额
                                    tmpRetDetail.accBal = startBalance;
                                }
                                String[] txndetails = txns[i].split(":86:");
                                if (txndetails.length > 1) {
                                    //:86
                                    //第1行：如果为“TOTAL CHARGE:”
                                    // 则该笔交易为一笔手续费交易记录，否则汇入汇款为银行内的交易序号或者为汇出汇款客户提交的交易序号。
                                    String txndetail = txndetails[1];
                                    String[] txn = txndetail.split(spliter, -1);
                                    //2行类型的MT940
                                    //:61:1811281128CY10800,67FTRFNONREF
                                    //:86:安联人寿保险费
                                    //00102018112801000048
                                    //:61:1811281128CY5394,FTRFNONREF
                                    //:86:安联人寿保险费
                                    //00102018112801000049
                                    if (txn.length >= 2 && txn.length < 6) {
                                        if (!txn[0].trim().contains("TOTAL CHARGE")) {
                                            tmpRetDetail.usage = txn[0].trim();
                                            tmpRetDetail.askNumber = txn[1].trim();
                                        } else {
                                            tmpRetDetail.usage = txn[0].trim();
                                            tmpRetDetail.recAccName = txn[1].trim();
                                        }
                                    } else if (txn.length >= 6) {
                                        String postscript = "";
                                        if (txn[0].contains("TOTAL CHARGE")) {
                                            tmpRetDetail.usage = txn[0];
                                            tmpRetDetail.reqBatchNO = txn[1].trim();
                                        } else {
                                            tmpRetDetail.reqBatchNO = txn[0].trim();
                                            tmpRetDetail.recAccName = txn[1];
                                        }
                                        if ("1".equals(cdFlag)) {
                                            if (!"".equals(txn[3])) {
                                                tmpRetDetail.recAccName = tmpRetDetail.recAccName + txn[2];
                                                postscript = txn[3];
                                            } else {
                                                postscript = txn[2];
                                            }
                                        } else {
                                            if (!"".equals(txn[2].trim())) {
                                                tmpRetDetail.recAccName = tmpRetDetail.recAccName + txn[2];
                                            }
                                            if (!"".equals(txn[3])) {
                                                postscript = txn[3];
                                            }
                                        }
                                        tmpRetDetail.recAccBank = txn[4];
                                        //交易附言解析
                                        String[] abstrs = postscript.split("\\+");
                                        tmpRetDetail.comment = postscript;
                                        tmpRetDetail.usage = postscript;
                                        if (abstrs.length > 1) {
                                            tmpRetDetail.abstr = abstrs[0];
                                            StringBuilder sb = new StringBuilder();
                                            for (int x = 1; x < abstrs.length; x++) {
                                                sb.append("+").append(abstrs[x]);
                                            }
                                            sb.delete(0, 1);
                                            tmpRetDetail.usage = sb.toString();
                                        }
                                        //账户余额
                                        tmpRetDetail.accBal = convertCommaToPoint(txn[5]).replace(",", "");
                                    }
                                }
                                retAts.writeRetDetail(tmpRetDetail);
                            }
                        }

                    }
                } catch (Exception ex) {
                    WriteBankLogLn("解析：" + fileName + " 文件异常：" + ex);
                }
            }
        }
    }

}
